//2022 12.21 16:45 星期三 晴

/**
 * user : 李巨松
 * purport : 建立一个 专享的 动态 效果
 */

/**
 * 业务 :
 * 1. 复制 元素 并 提取添加到 body 覆盖 原元素  将原元素 设置为 visibl:hidden;
 * 2. 将元素 添加 class 转移到 屏幕 中间 并 放大 || 其他元素 设置为 display none
 * 3. import 专享 组件 || 定位到 专属位置
 * 4. 空白区域 进行复原 按次序退出 显示 和 删除
 * 6. 恢复 至 起始操作
 */


// console.log("async start");

// async function avanda() {
// 	let ban = "first out"
// 	console.log(ban)
// 	await new Promise((a, b) => {
// 		a()
// 		console.log("await Promise")
// 	}).then(() => {
// 		ban = "Promise change"
// 		console.log(ban)
// 	})
// 	ban = "after await Promise change"
// 	console.log(ban)
// }
// avanda()

// console.log("async end");

/**
 * result
 * async start
 * first out
 * await Promise
 * async end
 * Promise change
 * after await Promise change
 */

// 目标元素
let targetElement

//复制 目标元素
let copyEl

let StaticCss = SetStaticCssTxtFunc("exclusiveElement")


function elClickHandler(e) {
	//settimeout 时间总线
	let timeline = 0
	//时间记录 线
	let timeObj = {
		data: []
	}

	//复制元素
	let cloneEl = cloneElementToBody(e.target)


	//调取到 需要保留的 其他元素
	let saveElArr = []
	//~~~~~~

	//添加 复制的元素
	saveElArr.push(cloneEl.id || cloneEl.className)
	//添加 shadow el
	saveElArr.push("window__shade")

	//隐藏 元素
	displayNoneBodyChildNodes(saveElArr)

	//自定義 clone 元素 居中的位置
	//调取到 clone 元素的 居中 animation class
	let cloneAnimationClass
	//~~~~~~

	//默认 的 复制元素 居中 class
	let defaultCenterClass = "default_Center"

	//調取 添加 臨時的default_center class style 標簽 函數


	//居中 时间
	//调取到 clone 元素的 居中 animation 之后 需要 停留的 时间
	let centerdelay = 0
	//~~~~~~

	//居中 clone 元素 所需要的时间
	let putcenterDelay = endsTimeAnimation(cloneEl, cloneAnimationClass || defaultCenterClass, centerdelay)

	//记录 居中延时
	timeline += Number(putcenterDelay)

	timeObj.data.push("putcenterDelay")
	timeObj["putcenterDelay"] = putcenterDelay

	//挂载目标元素
	let mountAppEl = document.createElement("div")
	mountAppEl.id = "temporayApp"
	document.body.appendChild(mountAppEl)


	//~~~~~~
	//mount 對應組件
	//利用 async await 运行吗?

	let mountTargetEl
	//~~~~~~
	//调取到 mount 的 目标 元素

	//根據位置信息 創建 臨時的 class animation 添加到 clone 元素
	assembleCenterToTargetKeyframe(centerToTarget_styleEl, cloneEl, mountTargetEl)
	//添加 class 到 dom

	// let centerToTargetDelay = endsTimeAnimation(cloneEl, )



	let activeObj = {}
	//~~~~~~
	//调取到 需要 active 的元素

	//过渡动画  展示一下 相关组件
	let showActiveDelay = showActiveClass(activeObj)

	//记录 过度动画延时
	timeline += Number(showActiveDelay)


	//在 rebackFunc 運行時 刪除此項數據
	//~~~~~~

	//reback 原路返回操作
	function rebackFunc() {
		//反轉 相關 class animation 0% 和 100% 數據
		//按序添加 
		//設置 clone元素 從 mount 位置 轉到 居中
		//mount 卸載 和 刪除 挂載 元素
		//復原 隱藏元素 的原display 居中 轉到 原位置

		//删除 添加的 本js 文件的 属性 和 添加到 html 的 style class

	}

	//返回 原路返回操作
	return rebackFunc

}

function calculatePosition(center, target) {
	let x1 = y1 = w1 = h1 = x2 = y2 = w2 = h2 = 0

	let cenEl = document.querySelector(center) || document.querySelector("." + center) || document.querySelector("#" +
		center)
	let tarEl = document.querySelector(target) || document.querySelector("." + target) || document.querySelector("#" +
		target)

	let comCenEl = window.getComputedStyle(cenEl)
	let comTarEl = window.getComputedStyle(tarEl)

	let cenPosi = getOffsetPosition(cenEl)
	let tarPosi = getOffsetPosition(tarEl)

	x1 = cenPosi.x
	y1 = cenPosi.y
	w1 = comCenEl.width
	h1 = comCenEl.height

	x2 = tarPosi.x
	y2 = tarPosi.y
	w2 = comTarEl.width
	h2 = comTarEl.height

	return {
		x1,
		y1,
		w1,
		h1,
		x2,
		y2,
		w2,
		h2
	}
}




/**
 * @param {Object} el
 */
function cloneElementToBody(el) {
	copyEl = el.cloneNode(true) || el

	let {
		x,
		y
	} = getOffsetPosition(el)

	//清空 复制元素的 内联样式
	copyEl.style = ""

	copyEl.style.position = "absolute";
	copyEl.style.left = x + 'px';
	copyEl.style.top = y + 'px';

	el.visible = "none"

	document.body.appendChild(copyEl)
	return copyEl
}










//tools
/*************   下面是一些 必要 工具 :)  ****************/

/**
 * 獲取 元素的 絕對 視窗定位
 * @param {Object} el 元素對象
 * @param {Object} str ["top"||"left"]
 * @return {Number}
 */
function getbodyOffsetPosition(el, str) {
	let keys = 'offset' + str[0].toUpperCase() + str.substring(1);
	let translateDire = str == 'top' ? 'translateY' : 'translateX';
	// console.log(keys);
	let num = 0;
	let elclone = el;
	for (; elclone['offsetParent'] != null;) {
		console.log(window.getComputedStyle(elclone));
		let matrixstr = window.getComputedStyle(elclone)['transform'];
		if (matrixstr != 'none') {
			let trans = spliteMatrix(matrixstr, translateDire);
			// console.log(trans);
			num += Number(trans);
		}
		// console.log(elclone, elclone['offsetParent']);
		num += Number(elclone[keys]);
		// console.log(num);
		elclone = elclone['offsetParent'];
	}
	return num;
}



/**
 * 修改 特定style标签 裏的 keyframe 一些既定參數
 * 大小 和 top left 位置
 * 
 * @param {Object} styleEl	--特定style标签
 * @param {Object} centerEl	--中間元素
 * @param {Object} targetEl	--目標元素
 */
function assembleCenterToTargetKeyframe(styleEl, centerEl, targetEl) {

	//獲取 元素的 位置 和 大小 
	function getElementPositionAndSize(el) {
		let comEl = window.getComputedStyle(el)

		let x = getbodyOffsetPosition("left")
		let y = getbodyOffsetPosition("top")
		let w = comEl.width
		let h = comEl.height

		return {
			x,
			y,
			w,
			h
		}
	}

	let posiCenter = getElementPositionAndSize(centerEl)

	let posiTarget = getElementPositionAndSize(targetEl)

	function assemblePosiFromTo(a, b) {
		return `\n\t\t\t\tfrom{\n\t\t\t\t\tleft: ${a.x};\n\t\t\t\t\ttop: ${a.y};\n\t\t\t\t\twidth: ${a.w};\n\t\t\t\t\theight: ${a.h};\n\t\t\t\t}\n\t\t\t\tto{\n\t\t\t\t\tleft: ${b.x};\n\t\t\t\t\ttop: ${b.y};\n\t\t\t\t\twidth: ${b.w};\n\t\t\t\t\theight: ${b.h};\n\t\t\t\t}`
	}
	let centerToTargetKeyframe = assemblePosiFromTo(posiCenter, posiTarget)


	changeKeyframe(styleEl, centerToTargetKeyframe)
}


/**
 * 根据 给定 keyframe 所有字段 替换 特定style标签 中的 keyframe
 * @param {Object} styleEl
 * @param {String} changedKeyframe
 */
function changeKeyframe(styleEl, changedKeyframe) {
	// console.log(styleEl);
	// console.log(changedKeyframe);
	if (styleEl.nodeName == "STYLE") {


		//keyframe 替換域 -- changeField
		let regKeyframeField = /@keyframes [^{]*? \{(?<changeField>[^]*)\}/

		//正则 执行后的 keyframe 字段 0 匹配字段 1 关键字段
		keyframeField = regKeyframeField.exec(styleEl.innerHTML)
		// console.log(keyframeField);
		// console.log(keyframeField.groups["changeField"]);

		//替换
		styleEl.innerHTML = styleEl.innerHTML.replace(keyframeField.groups["changeField"], changedKeyframe)
	}
}



// {
// 	idArr: ["string"],
// 	"id1": {
// 		"active": "string",
// 		"pass": "string"
// 	},
// 	"id2": {
// 		"active": "string",
// 		"pass": "string"
// 	}
// }
//展示 一下 active 时的 样式
//批量 添加 active default  class
//delay 時間 后 添加pass class
function showActiveClass(obj) {
	let idArray = "idArr"
	let activeClassIndex = "active"
	let deactiveClassIndex = "pass"
	let showdelay = 1500

	let maxtime = 0
	let maxtime0 = 0
	let maxtime1 = 0

	// elementId 是 对应 element id
	for (let elementId of obj[idArray]) {
		let el = document.getElementById(elementId)

		let activeClass = obj[elementId][activeClassIndex]
		let activeDelay = endsTimeAnimation(el, activeClass, showdelay)

		//active 的 最大 延迟时间
		maxtime0 = maxtime0 > activeDelay ? maxtime0 : activeDelay


		let deactiveClass = obj[elementId][deactiveClassIndex]
		let deactiveDelay = endsTimeAnimation(el, deactiveClass, activeDelay)

		//deactive 的 最大 延迟时间
		maxtime1 = maxtime1 > deactiveDelay ? maxtime1 : deactiveDelay

	}
	maxtime = Number(maxtime0) + Number(maxtime1)
	return maxtime
}

/**
 * 展示 元素
 * 目標元素 延迟添加 和 class animation 和 延遲删除 
 * @param {Object} el	--目標元素
 * @param {Object} animate	-- 動畫class
 * @param {Object} delay	-- 延遲添加
 * @param {Object} lateDrop	-- 延遲刪除
 * 
 * @return {Number} --延迟添加 和 animation 的時間 和 延遲删除 所用的時間
 */
function endsTimeAnimation(el, animate, delay, lateDrop) {
	if (!(el instanceof HTMLElement) || animate == undefined) {
		return 0
	}
	//返回結果
	let delayResult = 0

	delay = delay == undefined ? 0 : delay

	lateDrop = lateDrop == undefined ? 0 : lateDrop

	setTimeout(() => {
		// console.log(el);
		el.classList.add(animate);

		let comedEl = window.getComputedStyle(el);
		// console.log(comedEl);

		//目标 class 延迟时间
		let totalDelay = eval(parseFloat(comedEl.animationDuration.slice(0, -1)) + parseFloat(comedEl.animationDelay.slice(
			0,
			-1)));
		// console.log(totalDelay);

		setTimeout(() => {
			el.classList.remove(animate);
		}, Number(delay) + Number(totalDelay * 1000) + Number(lateDrop));
	}, delay)

	//賦值空元素 模擬計算 一次
	if (window.calcdomAnimateDelayEl == undefined) {
		let vac = document.createElement("div")
		document.appendChild(vac)
		window.calcdomAnimateDelayEl = vac
	}
	window.calcdomAnimateDelayEl.classList.add(animate)
	let a = window.getComputedStyle(window.calcdomAnimateDelayEl)
	let classDelay = eval(parseFloat(a.animationDuration.slice(0, -1)) + parseFloat(a.animationDelay.slice(
		0,
		-1)));
	//移除 模拟计算的 class
	window.calcdomAnimateDelayEl.classList.remove(animate)

	delayResult = Number(delay) + Number(classDelay * 1000) + Number(lateDrop)

	return delayResult
}



//获取元素 绝对 位置 返回 {x,y}
/**
 * @param {Object} el
 * @return {x,y}
 */
function getOffsetPosition(el) {

	let x = 0
	let y = 0

	let elclone = el

	//default  `` offset Top | Left


	// el father  `` scroll Top | Left
	// scrollTop
	// scrollLeft


	//transform   `` translate X | Y
	// let matrixstr = window.getComputedStyle(elclone)['transform'];
	// if (matrixstr != 'none') {
	// 	let trans = spliteMatrix(matrixstr, translateDire);
	// 	// console.log(trans);
	// 	num += Number(trans);
	// }

	do {
		x += Number(elclone["offsetLeft"]);
		y += Number(elclone["offsetTop"]);

		let matrixstr = window.getComputedStyle(elclone)['transform'];
		if (matrixstr != 'none') {
			let transX = spliteMatrix(matrixstr, 'translateX');
			let transY = spliteMatrix(matrixstr, 'translateY');
			// console.log(trans);
			x += Number(transX);
			y += Number(transY);
		}

		if (el != elclone) {
			x -= Number(elclone["scrollLeft"])
			y -= Number(elclone["scrollTop"])
		}
		elclone = elclone['offsetParent']
	} while (elclone['offsetParent'] != null)

	return {
		x,
		y
	};
}


/**
 * @param {String} matrStr
 * @param {String} type
 */
function spliteMatrix(matrStr, type) {
	if (!toStringTypeCheck(matrStr, 'string')) {
		console.log('sorry the arguments[0] is not String type');
		return false;
	}
	//matrix(1, 0, 0, 1, 0, -41.6)
	//matrix\((?<scalX>-?\d+(?:\.\d+)?),\s(?<skew>-?\d+(?:\.\d+)?),\s(?<rotate>-?\d+(?:\.\d+)?),\s(?<scalY>-?\d+(?:\.\d+)?),\s(?<translateX>-?\d+(?:\.\d+)?),\s(?<translateY>-?\d+(?:\.\d+)?)\)
	let resultArr = [];
	let regMatrixStr =
		/matrix\((?<scalX>-?\d+(?:\.\d+)?),\s(?<skew>-?\d+(?:\.\d+)?),\s(?<rotate>-?\d+(?:\.\d+)?),\s(?<scalY>-?\d+(?:\.\d+)?),\s(?<translateX>-?\d+(?:\.\d+)?),\s(?<translateY>-?\d+(?:\.\d+)?)\)/;
	let matchResult = matrStr.match(regMatrixStr);
	if (matchResult.groups) {
		for (let key in matchResult.groups) {
			resultArr[key] = matchResult.groups[key];
		}
		// console.log(resultArr);
		if (type != undefined) {
			if (!toStringTypeCheck(type, 'string')) {
				console.log('sorry the arguments[1] is not String type');
				return false;
			}
			return resultArr[type];
		} else {
			return resultArr;
		}
	}
}


/**
 * @param {Object} a
 * @param {String} type
 */
//tostring 类型检测 a 数据源 type 数据类型 （不分大小写）
function toStringTypeCheck(a, type) {
	if (type == undefined) {
		return false
	} else if (type.toLowerCase() == "any") {
		return true
	}
	// console.log(toString.call(a).slice(8, -1))
	return toString.call(a).slice(8, -1).toLowerCase() == type.toLowerCase()
}



//保留 某些元素 (按照 既定标签进行 隐藏 display:none;)
/**
 * @param {Array} saveElArr --nodename class id --(用的是 querySelector 按次序 查询 到第一个匹配到的 element)
 * @param {Array} typeArr
 */
function displayNoneBodyChildNodes(saveElArr, typeArr) {
	//获取元素的 所有 子元素
	let bodyChildeNodes = document.body.childNodes


	//默認 主要字段 --nav --footer (其他语义化 标签 body.childNodes)
	let defaultTypeArr = ["DIV", "P", "IMG", "BUTTON"]

	//typArr --如果有值 则是对 defaultTypeArr 的 补充
	if (typeArr == undefined) {
		typeArr = defaultTypeArr
	} else {
		for (var i = 0; i < defaultTypeArr.length; i++) {
			typeArr.indexOf(defaultTypeArr[i]) > -1 ? undefined : (typeArr.push(defaultTypeArr[i]))
		}
	}


	// console.log("typArr : " + typeArr);

	//被隐藏的元素
	let disElement = []

	let saveElements = []
	//放置 需要保留的元素
	for (let j = 0; j < saveElArr.length; j++) {
		let inv = document.querySelector(saveElArr[j]) || document.querySelector("." + saveElArr[j]) || document.querySelector(
			"#" + saveElArr[j])
		if (inv != undefined) {
			saveElements.push(inv)
		}
	}
	// console.log(saveElements);

	for (let i = 0; i < bodyChildeNodes.length; i++) {
		let nodeEl = bodyChildeNodes[i]
		// console.log("nodeName : " + nodeEl.nodeName);

		let indexN = typeArr.indexOf(nodeEl.nodeName)
		// console.log("in typArr index : " + indexN);

		//check 为常规元素 或者 选中的 元素
		if (indexN > -1) {

			// console.log(saveElements.indexOf(nodeEl) == -1);
			//不在 保留元素内
			if (saveElements.indexOf(nodeEl) == -1) {
				let comNodeEl = window.getComputedStyle(nodeEl)
				console.log(comNodeEl);

				//隐藏元素 内聯樣式
				nodeEl.style.display = "none"

				//添加 被隐藏的元素
				disElement.push(nodeEl)
			}
		}
	}


	/**
	 * 不传值 表示 恢复所有
	 * @param {Object} displayElArr
	 */
	function rebackElement(displayElArr) {
		if (displayElArr == undefined) {
			// displayElArr = "any"
			for (let i = 0; i < disElement.length; i++) {
				//根据 id 或 className(完整) 添加 display 的原先 样式
				// 如果 上面的返回值 为 undefined 则 取 nodeName 默认样式 的 值
				disElement[i].style.display = ""
			}

		} else {
			//复原部分元素
			for (let j = 0; j < displayElArr.length; j++) {
				let getElIndex = disElementHave(displayElArr[j])
				if (getElIndex > -1) {
					disElement[getElIndex].style.display = ""
				}
			}
		}

		//检测 disElement 中 是否包含了 某项元素
		function disElementHave(targetel) {
			for (let i = 0; i < disElement.length; i++) {
				disElement[i] == targetel
				return i
			}
			return -1
		}
	}
	return rebackElement
}


//反轉 animation 0% 40% 100% 按照 0%(100%) 60(40%) 100%(0%)
//from to  兩個值 轉換 返回 转换后的值
/**
 * 反轉 animation 0% 40% 100% 按照 0%(100%) 60(40%) 100%(0%) 保留 后两位小数
 * @param {Object} keyframes --仅限 keyframes 字段
 */
function rebackAnimation(keyframes) {
	//匹配 % | from to 字段名 和 `{[^}]*?}` 最小字段數據
	//groups 字段 -- num | from | to | keyframe
	let REkeyframesGroups = /(?:(?<num>[^{]{1,5})%|(?<from>from)|(?<to>to)) (?<keyframe>\{[^}]*?\})/g

	//簡單 trim 一下 方便 匹配 字段
	let trimKeyframes = keyframes.trim()

	//記錄原始數據的 對象 --data 調取 索引對象key
	let loopArr = {
		data: []
	}

	//每次 循環 的匹配值
	let regResult

	//反轉 loopArr
	let reLoopArr = {
		data: []
	}

	//REloop 補齊字段
	let joinstr = ""

	do {
		//獲取 匹配字段
		regResult = REkeyframesGroups.exec(trimKeyframes)
		console.log(regResult);

		if (regResult != null) {
			//提取 groups
			let reGroups = regResult.groups

			switch (true) {
				//提取 from 信息
				case reGroups["from"] != undefined:

					// console.log("from");
					//放入 from key
					loopArr["data"].push("from")
					loopArr["from"] = reGroups.keyframe

					break;

					//提取 to 信息
				case reGroups["to"] != undefined:

					// console.log("to");
					//放入 to key
					loopArr["data"].push("to")
					loopArr["to"] = reGroups.keyframe
					break;

					//提取 name 信息
				case reGroups["num"] != undefined:

					// console.log("num", reGroups["num"]);
					//放入 num key
					loopArr["data"].push(reGroups.num)
					loopArr[reGroups.num] = reGroups.keyframe
					break;
			}
		}
	} while (regResult != null)

	console.log(loopArr);

	function reKeyframe() {
		let reKeyframeBody = /@keyframes [^{]*? \{(?<changeField>[^]*)\}/
		for (var i = 0; i < loopArr["data"].length; i++) {
			if (loopArr["data"][i] == "from") {

				reLoopArr["data"].push("to")
				reLoopArr["to"] = loopArr[loopArr["data"][i]]

			} else if (loopArr["data"][i] == "to") {

				reLoopArr["data"].push("from")
				reLoopArr["from"] = loopArr[loopArr["data"][i]]

			} else if (Number(loopArr["data"][i]) <= 100) {

				let reNumber = 100 - Number(loopArr["data"][i])
				let keyaframe = (reNumber | 0) === reNumber ? reNumber : reNumber.toFixed(2)
				reLoopArr["data"].push(keyaframe)
				reLoopArr[keyaframe] = loopArr[loopArr["data"][i]]

			}
		}

		//補齊 字段
		if (reLoopArr["from"] != undefined) {

			joinstr += `\n\t${reLoopArr["from"]} ${reLoopArr["from"]}\n\t${reLoopArr["to"]} ${reLoopArr["to"]}`

		} else {
			//重排序 默認 遞增排序
			reLoopArr["data"].sort((a, b) => a - b)
			console.log(reLoopArr["data"]);

			for (var i = 0; i < reLoopArr["data"].length; i++) {
				//添加 補齊 字段
				joinstr += `\n\t${reLoopArr["data"][i]}% ${reLoopArr[reLoopArr["data"][i]]}`

			}
			joinstr += "\n"
		}

		console.log(joinstr)

		let rekeyBody = reKeyframeBody.exec(trimKeyframes)
		console.log(rekeyBody);

		if (rekeyBody != null) {
			let rekeyBodyGs = rekeyBody.groups
			console.log(rekeyBodyGs["changeField"]);
			console.log(trimKeyframes)
			let rekeyframed = trimKeyframes.replace(rekeyBodyGs["changeField"], joinstr)
			//綁定 style 到 標簽
			// (不是自動綁定 可以進行數據的監聽) :(
			console.log(rekeyframed)
			return rekeyframed
		}

	}

	return reKeyframe()
}



//建立 唯一 臨時的 style 標簽 到 head 
/**
 * @param {String} id
 */
function SetStaticCssTxtFunc(id) {
	window.StaticCss = window.StaticCss ? function() {
		let a = window.StaticCss
		a["id"].indexOf(id) == -1 ? function() {
			a["id"].push(id)
			a[id] = {
				classArr: []
			}
		}() : undefined
		return a

	}() : function() {
		let a = {}
		a["id"] = [id]
		a[id] = {
			classArr: []
		}
		return a
	}()
	let totalStaticCss = window.StaticCss

	return function(cla, code) {
		if (cla == undefined && code == undefined) {
			//返回 縂的 已經定義的 元素
			return claArr
		}
		// console.log(claArr);
		if (cla == undefined) {
			console.log("sorry we need a id to manage the variable \n plase enter a arguments[0] value")

			return null
		}


		var hasClaCss = false
		// console.log("沒進來 ");
		let claArr = totalStaticCss[id]
		// console.log(claArr);

		claArr["classArr"].indexOf(cla) == -1 ? function() {
			// console.log("添加")
			claArr["classArr"].push(cla)
			claArr[cla] = code
		}() : function() {
			hasClaCss = true
			// console.log("添加過了")

			//cover style code
			let targetStyle = document.getElementById(cla)
			try {
				//for Chrome Firefox Opera Safari
				targetStyle.appendChild(document.createTextNode(code))
			} catch (ex) {
				//for IE
				targetStyle.styleSheet.cssText = code
			}
		}()


		if (hasClaCss == true) {
			// console.log("you have settled \"" + cla + "\" id CssStyle Now!  In head tag");
			return true
		}
		if (code != undefined) {
			var style = document.createElement('style')
			style.type = 'text/css'
			style.rel = 'stylesheet'
			try {
				//for Chrome Firefox Opera Safari
				style.appendChild(document.createTextNode(code))
			} catch (ex) {
				//for IE
				style.styleSheet.cssText = code
			}
			style.setAttribute("class", `static_${cla}`)
			style.setAttribute("id", `${cla}`)

			var head = document.getElementsByTagName('head')[0]
			head.appendChild(style)
		} else if (code == "remove") {
			if (claArr["classArr"].indexOf(cla) != -1) {
				claArr["classArr"].splice(claArr["classArr"].indexOf(cla), 1)
				// console.log(claArr);
				var claEle = document.getElementById(`${cla}`)
				claEle.remove()
				return `${cla} has been removed`
			}
			return `${cla} is undefined`
		} else if (code == undefined) {
			if (claArr["classArr"].indexOf(cla) != -1) {
				//返回 指定的 class
				return claArr["classArr"][cla]
			}
			return `${cla} is undefined`
		}

	}
}

//×××××××××××××××××× 遺棄 !!!!!!!!! 因爲改變前面的字段後面的就會受影響 需要更多的 測序 及 判斷 ××××××××××××××××××
// //替換 String groups 組中 的 數據 返回 String
// function replaceGi(reg, groupi, restr) {
// 	console.log(this);
// 	console.log(reg, groupi, restr);

// 	//調取 匹配的 groups
// 	let groups = this.match(reg).groups

// 	if (toStringTypeCheck(groupi, "string") && toStringTypeCheck(restr, "string")) {
// 		if (groups[groupi] != undefined) {
// 			return this.replace(groups[groupi], restr)
// 		}
// 	} 
// 	//else if (toStringTypeCheck(groupi, "object")) {
// 	// 	for (let i in groupi) {
// 	// 		if (groups[i] != undefined) {
// 	// 			return this.replace(groups[i], groupi[i])
// 	// 		}
// 	// 	}
// 	// }
// }

// String.prototype.replaceGi = replaceGi
// let ad = `aabbc`
// let regf=/(?<avanda>a)a(?<monika>b)/
// ad.replaceGi(regf, "monika","777")
